/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.tg.cms.entity;

import com.tg.smsgw.ws.AppAuthenticator;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import telsoft.admin.util.AppServer;
import telsoft.sql.Database;
import telsoft.util.DateUtil;
import telsoft.util.StringUtil;

/**
 *
 * @author tuanta
 */
public class DownloadTicket {
    public static String BASE_DOWNLOAD_LINK = "http://3one.vn:8686/game/download.jsp?c=";
    public static String TICKET_ERROR_CODE_NOT_FOUND = "code_not_found";
    public static String TICKET_ERROR_INVALID_LOGIN = "01";
    public static String TICKET_ERROR_CODE_EXPIRED = "code_expired";
    public static String TICKET_ERROR_MAX_DOWNLOAD_EXCEEDED = "max_download_exceeded";
    public static String TICKET_ERROR_INTERNAL = "internal";
    public static String TICKET_SUCCESS = "success";
    public static String TICKET_REGULAR = "regular";
    public static String TICKET_MASTER = "master";
    Connection cn = null;
    String downloadCode;
    String downloadLink;
    String deviceOS;
    String ticketType;

    Date validFrom;
    Date validUntil;
    int itemID;
    Date requestDate;
    int downloadCount;
    int maxDownload;
    MDItem item;
    boolean ticketFound = false;

    public String getTicketType() {
        return ticketType;
    }

    public void setTicketType(String ticketType) {
        this.ticketType = ticketType;
    }

    public String getDeviceOS() {
        return deviceOS;
    }

    public void setDeviceOS(String deviceOS) {
        this.deviceOS = deviceOS;
    }

    public MDItem getItem() {
        return item;
    }

    public String getDownloadCode() {
        return downloadCode;
    }

    public void setDownloadCode(String downloadCode) {
        this.downloadCode = downloadCode;
    }

    public Date getValidFrom() {
        return validFrom;
    }

    public void setValidFrom(Date validFrom) {
        this.validFrom = validFrom;
    }

    public Date getValidUntil() {
        return validUntil;
    }

    public void setValidUntil(Date validUntil) {
        this.validUntil = validUntil;
    }

    public int getItemID() {
        return itemID;
    }

    public void setItemID(int itemID) {
        this.itemID = itemID;
    }

    public Date getRequestDate() {
        return requestDate;
    }

    public void setRequestDate(Date requestDate) {
        this.requestDate = requestDate;
    }

    public int getDownloadCount() {
        return downloadCount;
    }

    public void setDownloadCount(int downloadCount) {
        this.downloadCount = downloadCount;
    }

    public int getMaxDownload() {
        return maxDownload;
    }

    public void setMaxDownload(int maxDownload) {
        this.maxDownload = maxDownload;
    }
    public String validateTicket(){
        if(!ticketFound){
            return TICKET_ERROR_CODE_NOT_FOUND;
        }
        if(getDownloadCount()==getMaxDownload()){
            return TICKET_ERROR_MAX_DOWNLOAD_EXCEEDED;
        }
        if((new Date()).after(getValidUntil())){
            return TICKET_ERROR_CODE_EXPIRED;
        }
        return TICKET_SUCCESS;
    }

    public String getDownloadLink() {
        return downloadLink;
    }

    public void setDownloadLink(String downloadLink) {
        this.downloadLink = downloadLink;
    }
    
    /* processDownloadRequest 
     * 1. accepts downloadCode and validate it
     * 2. if validation succeeds, then query MD_ITEMS for actual requested item
     * outside JSP page will use it for sending to user
     */
    public String processDownloadRequest(){
        try {
            cn = AppServer.getConnection();
            /* fill out ticket information, given that ticket code has been set */
            queryTicketByCode();
            /* is ticket still valid? */
            String validateResult = validateTicket();
            if (!validateResult.equals(TICKET_SUCCESS)){
                return validateResult;
            }
            /* now, fill out the coresponding MDItem */
            item = new MDItem();
            item.setItemID(String.valueOf(getItemID()));
            item.setCn(cn);
            item.queryItemById();
            /* increase download count */
            updateDownloadCount();
            return TICKET_SUCCESS;
        } catch (Exception ex) {
            Logger.getLogger(DownloadTicket.class.getName()).log(Level.SEVERE, null, ex);
            return TICKET_ERROR_INTERNAL;
        }
        finally{
            Database.closeObject(cn);
        }
    }
    public void updateDownloadCount() throws Exception{
        Statement stmt = null;
        String strSQL = "UPDATE DOWNLOAD_TICKETS SET DOWNLOAD_COUNT = NVL(DOWNLOAD_COUNT, 0) + 1 WHERE DOWNLOAD_CODE = '" + getDownloadCode() + "'";
        try {
            stmt = cn.createStatement();
            stmt.executeUpdate(strSQL);
        }
        finally{
            Database.closeObject(stmt);
        }
    }
    
    public void queryTicketByCode() throws Exception{
        Statement stmt = null;
        ResultSet rsTicket = null;
        
        String strSQL = "SELECT download_code,to_char(valid_from,'dd/mm/yyyy hh24:mi:ss') valid_from, to_char(valid_until,'dd/mm/yyyy hh24:mi:ss') valid_until,"
                + "item_id, to_char(request_date,'dd/mm/yyyy hh24:mi:ss') request_date, max_download, download_count, ticket_type, device_os "
                + "FROM DOWNLOAD_TICKETS WHERE DOWNLOAD_CODE = '" + getDownloadCode() + "'";
        try {
            stmt = cn.createStatement();
            rsTicket = stmt.executeQuery(strSQL);
            while(rsTicket.next()){
                ticketFound = true;
                setDownloadCount(rsTicket.getInt("download_count"));
                setItemID(rsTicket.getInt("item_id"));
                setMaxDownload(rsTicket.getInt("max_download"));
                setDownloadCount(rsTicket.getInt("download_count"));
                setRequestDate(DateUtil.toDate(rsTicket.getString("request_date"), "dd/MM/yyyy HH:mm:ss"));
                setValidFrom(DateUtil.toDate(rsTicket.getString("valid_from"), "dd/MM/yyyy HH:mm:ss"));
                setValidUntil(DateUtil.toDate(rsTicket.getString("valid_until"), "dd/MM/yyyy HH:mm:ss"));
                setTicketType(rsTicket.getString("ticket_type"));
                setDeviceOS(rsTicket.getString("device_os"));
            }
        }
        finally{
            Database.closeObject(stmt);
        }
    }
    /* processLinkRequest 
     * 1. generate download code and returns link to download
     */
    public String processLinkRequest(String itemID, String username, String password, String partnercode){
        try {
            cn = AppServer.getConnection();
            AppAuthenticator aa = new AppAuthenticator();
            aa.setConnection(cn);
            try{
                aa.verifyPassword(username,  StringUtil.encrypt(password, "SHA"));
            }
            catch(Exception e){
                e.printStackTrace();
                return TICKET_ERROR_INVALID_LOGIN;
            }
            /* now, fill out the coresponding MDItem */
            item = new MDItem();
            item.setItemID(String.valueOf(getItemID()));
            item.setCn(cn);
            item.queryItemById();
            return TICKET_SUCCESS;
        } catch (Exception ex) {
            Logger.getLogger(DownloadTicket.class.getName()).log(Level.SEVERE, null, ex);
            return TICKET_ERROR_INTERNAL;
        }
        finally{
            Database.closeObject(cn);
        }
    }
    public static DownloadTicket getDownloadTicket(String downloadCode, String deviceOS){
        Connection cn = null;
        PreparedStatement pstmt = null;
        ResultSet rsTicket = null;
        
        String strSQL = "SELECT download_code,to_char(valid_from,'dd/mm/yyyy hh24:mi:ss') valid_from, to_char(valid_until,'dd/mm/yyyy hh24:mi:ss') valid_until,"
                + "item_id, to_char(request_date,'dd/mm/yyyy hh24:mi:ss') request_date, max_download, download_count, ticket_type, device_os "
                + "FROM DOWNLOAD_TICKETS WHERE DOWNLOAD_CODE = ? OR MASTER_CODE = ?";
        ArrayList<DownloadTicket> downloadTicketList = new ArrayList<DownloadTicket>();
        try {
            cn = AppServer.getConnection();
            pstmt = cn.prepareStatement(strSQL);
            pstmt.setString(1, downloadCode);
            pstmt.setString(2, downloadCode);
            rsTicket = pstmt.executeQuery();
            while(rsTicket.next()){
                DownloadTicket ticket = new DownloadTicket();
                ticket.setDownloadCode(rsTicket.getString("download_code"));
                ticket.setDownloadCount(rsTicket.getInt("download_count"));
                ticket.setItemID(rsTicket.getInt("item_id"));
                ticket.setMaxDownload(rsTicket.getInt("max_download"));
                ticket.setDownloadCount(rsTicket.getInt("download_count"));
                ticket.setRequestDate(DateUtil.toDate(rsTicket.getString("request_date"), "dd/MM/yyyy HH:mm:ss"));
                ticket.setValidFrom(DateUtil.toDate(rsTicket.getString("valid_from"), "dd/MM/yyyy HH:mm:ss"));
                ticket.setValidUntil(DateUtil.toDate(rsTicket.getString("valid_until"), "dd/MM/yyyy HH:mm:ss"));
                ticket.setTicketType(rsTicket.getString("ticket_type"));
                ticket.setDeviceOS(StringUtil.nvl(rsTicket.getString("device_os"),""));
                downloadTicketList.add(ticket); 
            }
//            if there's only one ticket found, return it
//            System.out.println("Looking for device:" + deviceOS);
            if(downloadTicketList.size()==1)
                return downloadTicketList.get(0);
            else{
                for (int i = 0; i < downloadTicketList.size(); i++) {
                    DownloadTicket downloadTicket = downloadTicketList.get(i);
                    if (downloadTicket.getDeviceOS().equals(deviceOS) && downloadTicket.getTicketType().equals(DownloadTicket.TICKET_REGULAR)){
                        return downloadTicket;
                    }
                }
                for (int i = 0; i < downloadTicketList.size(); i++) {
                    DownloadTicket downloadTicket = downloadTicketList.get(i);
                    if (downloadTicket.getTicketType().equals(DownloadTicket.TICKET_REGULAR) && downloadTicket.getDeviceOS().equals("")){
                        return downloadTicket;
                    }
                }
                return null;
            }
        }
        catch(Exception e){
            e.printStackTrace();
            return null;
        }
        finally{
            Database.closeObject(pstmt);
            Database.closeObject(cn);
        }
    }
}
